/**
 * 
 */

/**
 * Management object view definition.
 */
var nt1 = '<tr id="#p"><td id="name">#p</td><td id="vcl">#p</td><td id="active">#p</td></tr>';
var manage = {
	
	_html:'<div class="node" id="#p"><div id="node-header"><div id="text">#p</div><div id="nav"><span id="newvcl">VCL</span><span id="start">start</span><span id="stop">stop</span></div></div>' + 
			'<div id="ban-container"><div id="ban-label">Ban </div><div id="ban"><input type="text" id="ban-expression" /></div><div id="ban-execute"><input type="button" value="execute" id="execute" /></div></div><div id="info">' + 
			'<div id="monitor">' + 
			'<div class="child"><p class="name">Hit Ratio (%)</p><p class="value">#p</p><div id="hitratio"></div></div>' + 
			'<div class="child"><p class="name">Request (#)</p><p class="value">#p</p><div id="request"></div></div>' + 
			'<div class="child"><p class="name">Accepted (#)</p><p class="value">#p</p><div id="accept"></div></div>' + 
			'<div class="child"><p class="name">Hit (#)</p><p class="value">#p</p><div id="hit"></div></div>' + 
			'<div class="child"><p class="name">Hit-Pass (#)</p><p class="value">#p</p><div id="hitpass"></div></div>' + 
			'<div class="child"><p class="name">Miss (#)</p><p class="value">#p</p><div id="miss"></div></div></div>' + 
			'<div id="configuration"><div id="vcl" class="child"></div><div id="prop" class="child last-child"></div></div></div>' + 
			'</div>',
	_vcl: '<div id="vcl-container"><div id="vcl-name">#p</div><div id="vcl-status"></div></div>',
	
	show: function () {	$('#management').css('display', 'block'); },
	afterShow: function() {	$.sparkline_display_visible(); },
	hide: function () { $('#management').css('display', 'none'); },
	render: function(o) {
		if(o.status!=200) {
			this.ko(o);
		} else {
			this.ok(o);
		}
	},
	rate: function(ss) {
		var ra=[],aa=[],ha=[],ma=[],hpa=[],hra=[],lre=0,lac=0,lhi=0,lhp=0,lmi=0;
		if(F.valid(ss) && ss.length>0) {
			var last = ss.length-1;
			for(var k=last; k>=0; k--) {
				var s = ss[k];
				ra[last-k] = s.requested;
				aa[last-k] = s.accepted;
				ha[last-k] = s.hit;
				ma[last-k] = s.miss;
				hpa[last-k] = s.hitpass;
				var tot = s.hit + s.miss + s.hitpass;
				if(tot>0) {
					hra[last-k] = F.round((s.hit / tot) * 100, 2);
				} else {
					hra[last-k] = 0;
				}
				 
			}
			if(ss.length == 1) {
				lre = ra[last];
				lac = aa[last];
				lhi = ha[last];
				lhp = hpa[last];
				lmi = ma[last];
			} else {
				lre = ra[last] - ra[last-1];
				lac = aa[last] - aa[last-1];
				lhi = ha[last] - ha[last-1];
				lhp = hpa[last] - hpa[last-1];
				lmi = ma[last] - ma[last-1];
			}
		}
		return {'requested':ra,'accepted':aa,'hit':ha,'miss':ma,'hitpass':hpa,'hitratio':hra,
			'lastRequested':lre,'lastAccepted':lac,'lastHit':lhi,'lastHitpass':lhp,'lastMiss':lmi};
	},
	get: function(pid, cid) { return $('#'+pid).find('#'+cid); },
	/**
	 * Render the view in case of success
	 * @param o the response object to have to render
	 */
	ok: function(o) {
		var r = o.data;
		var ns = $('#management #nodes');
		if(!F.valid(ns)) {
			this.ko({status:404,message:"Unable to find DOM node object", data:null});
			return false;
		}
		ns.empty();
		for(var k in r) {
			var n = r[k]['node'], vs = r[k]['vcl'], ps = r[k]['params'], ss = r[k]['snapshots'];
			var stats = this.rate(ss);
			var text = F.concat(" ", "&nbsp;",n.name,"@",n.hostname,"[",r[k]['version'],"]");
			var id = n.id;
			var hra = stats['hitratio'];
			var hr = hra.length>0 ? hra[ss.length - 1] : 0;
			var node = $(F.replace("#p", [id,text, hr, stats['lastRequested'], stats['lastAccepted'], stats['lastHit'], stats['lastHitpass'], stats['lastMiss']], this._html));
			ns.append(node);
			
			node.find('#newvcl').click(function(e) {
				F.editor.init({ container: node, id: id });
				var dateMs = new Date().getTime();
				F.editor.render({code:"", name: "vcl-" + dateMs});
				F.editor.show();
			});
			
			node.find('.child #hitratio').sparkline(stats['hitratio'], {height:'40px',width:'100px'});
			node.find('.child #request').sparkline(stats['requested'], {height:'40px',width:'100px'});
			node.find('.child #accept').sparkline(stats['accepted'], {height:'40px',width:'100px'});
			node.find('.child #hit').sparkline(stats['hit'], {height:'40px',width:'100px'});
			node.find('.child #hitpass').sparkline(stats['hitpass'], {height:'40px',width:'100px'});
			node.find('.child #miss').sparkline(stats['miss'], {height:'40px',width:'100px'});
			
			node.find('#execute').click(function() {alert("Ban!");});
			
			var vcl = node.find('#vcl');
			for(var c in vs) {
				var v = vs[c];
				if(v.hasError) {
					
				} else {
					var cv = $(F.replace("#p", [v.name=="boot" ? "default" : v.name], this._vcl));
					vcl.append(cv);
					cv.find('#vcl-status').css({'background-color': (v.status=="active" ? 'green' : 'orange')});
					cv.click(function(){
						var name = $(this).find('#vcl-name').text();
						if(F.equals(name,"default")) {
							// XXX check the status if not active activate it.
							return;
						}
						var id = $(this).closest('.node').attr('id');
						F.ajax('node/show/'+id+"?name="+name,'GET',null,false,true,null,
								function(resp){
									F.editor.init({ container: node, id: id });
									F.editor.render({code:resp[0], name: name});
									F.editor.show();
								},
								function(resp){alert("Error!! " + resp);});
					});
				}
			}
			var pp = node.find('#prop');
			var table = $('<table/>').attr('id','prop-container').append($('<thead/>').append($('<tr/>').append($('<td/>').text('Parameter'),$('<td/>').text('Value'))));
			var tbody = $('$<tbody/>');
			for(var c in ps) {
				var p = ps[c];
				if(p.hasError) {
					
				} else {
					tbody.append($('<tr/>').append($('<td/>').text(p.name),$('<td/>').text(p.value + " " + p.info)));
				}
			}
			pp.append(table.append(tbody));
		}
	},
	/**
	 * Render the view in case of failure
	 * @param o the response object to have to render
	 */
	ko: function(o) {
		$('#management').text(F.concat(" - ", o.status, o.message));
	}
	
}
/**
 * Management controller
 */
var ManagementController = Controller.extend({
	init: function() {
		this.view = View.extend(manage);
	},
	execute: function() {
		// Executes the HTTP call synchronously, as soon that it is complete return the view.
		F.ajax('node/configuration', 'GET', null, false, false, this, this.cb, null);
		return this.view;
	},
	cb: function(resp) { this.view.render(resp); },
});
F.addController('man', ManagementController);

/**
 * Monitoring view object definition
 */
var nt = '<tr id="#p"><td id="name">#p</td><td id="req">#p</td></tr>';
var monitor = {
	
	init: function() {
	},
	show: function() {
		$('#monitor').css('display', 'block');
	},
	hide: function() {
		$('#monitor').css('display', 'none');
	},
	render: function(r) {
		var ns = $('#monitor #nodes');
		if(!F.valid(ns)) {
			alert("Unable to find nodes canvas");
			return false;
		}
		ns.empty();
		for(var k in r) {
			ns.append(F.replace('#p',[r[k].id, r[k].name, r[k].hostname],nt));
		}
	}
};
/**
 * Monitoring controller implementation
 */
var MonitorController = Controller.extend({
	init: function() {
		this.view = View.extend(monitor);
	},
	execute: function() {
		F.ajax('node/list', 'GET', null, false, false, this, this.scb, this.ecb);
		if(!F.valid(this.response)) {
			alert("not valid");
			return null;
		} else {
			this.view.render(this.response);
			return this.view;
		}
	},
	scb: function(resp) {
		this.response = resp;
	}
});
F.addController('mon', MonitorController);